﻿using OperationPlugins.Validators;
using OperationPlugins.Validators.DataAnnotations;
using System;
using System.Collections.ObjectModel;
using System.Runtime.Remoting.Messaging;

namespace OperationPlugins
{
    /// <summary>
    /// This is the operation plugins context.
    /// </summary>
    [Serializable]
    public sealed class OperationPluginsContext : MarshalByRefObject, ILogicalThreadAffinative
    {
        private readonly MessageContainer _messages = new MessageContainer();

        /// <summary>
        /// Switches the current OperationPluginsContext.
        /// </summary>
        /// <param name="newContext">The new OperationPluginsContext.</param>
        public static void SwitchContext(OperationPluginsContext newContext)
        {
            if (newContext == null)
            {
                throw new ArgumentNullException("newContext");
            }

            ContextStorage.Set<OperationPluginsContext>(newContext);
        }

        /// <summary>
        /// Gets the current OperationPluginsContext object.
        /// </summary>
        public static OperationPluginsContext Current
        {
            get { return ContextStorage.Get<OperationPluginsContext>(); }
        }

        /// <summary>
        /// Gets the message container.
        /// </summary>
        public MessageContainer Messages
        {
            get { return _messages; }
        }

        /// <summary>
        /// Adds messages to this OperationPluginsContext object.
        /// </summary>
        /// <param name="messages">The messages to be added.</param>
        public void Add(MessageContainer messages)
        {
            Messages.Add(messages);
        }

        /// <summary>
        /// Gets a Boolean value indicating whether this OperationPluginsContext object 
        /// contains any error messages.
        /// </summary>
        public bool ContainsErrors
        {
            get { return Messages.ContainsErrors; }
        }

        /// <summary>
        /// Gets a Boolean value indicating whether this OperationPluginsContext object 
        /// contains any notification messages.
        /// </summary>
        public bool ContainsNotifications
        {
            get { return Messages.ContainsNotifications; }
        }

        /// <summary>
        /// Gets all error messages.
        /// </summary>
        public ReadOnlyCollection<Message> Errors
        {
            get { return Messages.Errors; }
        }

        /// <summary>
        /// Gets all notification messages.
        /// </summary>
        public ReadOnlyCollection<Message> Notifications
        {
            get { return Messages.Notifications; }
        }

        /// <summary>
        /// Gets and sets the OperationId for the current action.
        /// </summary>
        public OperationId CurrentActionOperation { get; set; }

        /// <summary>
        /// Gets and sets the BrachId for the current action.
        /// </summary>
        public BranchId CurrentActionBranch { get; set; }

        /// <summary>
        /// Gets and sets the value indicating should the current action ignore all <see cref="UsePluginValidatorsAttribute"/> attributes.
        /// </summary>
        public bool DisablePluginsValidation { get; set; }

        /// <summary>
        /// Clears messages from this context. 
        /// </summary>
        public void ClearResults()
        {
            Messages.Clear();
        }

    }
}
